<template>
	<div class="map">
		<div id="container" />
		<div>
			<input
				v-model="size"
				@input="sizeChange"
				type="range"
				min="0"
				max="100"
			/>
			{{ size }}
		</div>
	</div>
</template>

<script>
import AMapLoader from "@amap/amap-jsapi-loader";
import data from "./data.js";

let geocoder = null;

let scatterInstanceAll = [];

export default {
	data() {
		return {
			// map:null,
			zoom: 3.8,
			size: 0,
		};
	},
	async mounted() {
		await this.initMap();
		this.drawScatterMap();
	},
	methods: {
		/** @name 初始化地图 **/
		initMap() {
			return new Promise((resolve) => {
				window._AMapSecurityConfig = {
					securityJsCode: "",
				};
				AMapLoader.load({
					key: "",
					version: "2.0",
					plugins: ["AMap.Geocoder"],
				})
					.then((AMap) => {
						this.map = new AMap.Map("container", {
							center: [110.17293, 35.20173],
							zoom: this.zoom, // 缩放级别
						});
						this.map.on("complete", () => {
							resolve();
						});
					})
					.catch((e) => {
						console.log(e);
					});
			});
		},
		/** @name 获取随机颜色 **/
		getRandomColor() {
			let color = "#";
			for (let i = 0; i < 6; i++) {
				color += ((Math.random() * 16) | 0).toString(16);
			}
			return color;
		},
		/** @name 根据地址从高德获取地址的经纬度信息 **/
		geoCode(address) {
			return new Promise((resolve) => {
				if (!geocoder) {
					geocoder = new window.AMap.Geocoder();
				}
				geocoder.getLocation(address, (status, result) => {
					if (status === "complete" && result.geocodes.length) {
						const lnglat = result.geocodes[0].location;
						resolve(lnglat);
					} else {
						console.warn("根据地址查询位置失败：" + address);
					}
				});
			});
		},
		/** @name 散点大小 **/
		sizeChange() {
			this.drawScatterMap();
		},
		/** @name 绘制散点地图 **/
		async drawScatterMap() {
			// 清空
			if (scatterInstanceAll.length > 0) {
				this.map.remove(scatterInstanceAll);
				scatterInstanceAll = [];
			}

			for (const [index, address] of data.entries()) {
				let center = [address.lng, address.lat];
				// 兼容缺失经纬度坐标的数据
				if (!center[0] || !center[1]) {
					// 前端通过高德API自行查经纬度
					const result = await this.geoCode(address.append);
					center = [result.lng, result.lat];
					// 如果还是查不到经纬度，就放弃这个点
					if (!center[0] || !center[1]) continue;
				}
				if (center[0] && center[1]) {
					// 计算半径大小
					let radius = 5 + (64 - 5) * (this.size / 100);
					const color = this.getRandomColor();
					const scatterInstance = new window.AMap.CircleMarker({
						center, // 经纬度坐标
						radius, // 散点半径: 0~64
						fillColor: color, // 填充颜色, 仅支持16进制颜色值, 默认值为#00D3FC
						fillOpacity: 0.8, // 填充颜色透明度
						strokeColor: color, // 边框颜色
						strokeWeight: 1, // 边框大小
						zIndex: index, // 层级: 层级越高越靠上方
						cursor: "pointer", // 指定鼠标悬停时的鼠标样式
						clickable: true, // 点标记是否可点击
						extData: {
							// 额外自定义属性
							index,
							address,
						},
					});
					scatterInstance.setMap(this.map);
					scatterInstanceAll.push(scatterInstance);
					// 绑定交互事件
					scatterInstance.on("click", (e) => {
						const extData = e.target._opts.extData;
						console.log(extData);
					});
					scatterInstance.on("mouseover", (e) => {
						const extData = e.target._opts.extData;
						// 点散层级调大
						scatterInstanceAll[extData.index].setOptions({
							zIndex: data.length + 10,
						});
					});
					scatterInstance.on("mouseout", (e) => {
						const extData = e.target._opts.extData;
						scatterInstanceAll[extData.index].setOptions({
							zIndex: extData.index,
						});
					});
				}
			}
		},
	},
};
</script>

<style scoped>
.map {
	width: 740px;
	height: 500px;
	position: relative;
	display: flex;
	justify-content: flex-start;
	align-items: flex-start;
}
#container {
	width: 100%;
	height: 100%;
	margin-right: 10px;
}
</style>
